
<template>
  <lay-card width="1200" style="height: 860px;">
    <lay-row>
      <lay-col md="16">
        <lay-row space="1">
          <lay-col md="24">
            <lay-quote size="sm">
              <div style="margin-left: 50px">
                <lay-row>
                  <lay-col md="4"><lay-radio v-model="selected" name="action" value="1">环境检查</lay-radio></lay-col>
                  <lay-col md="4"><lay-radio v-model="selected" name="action" value="2">切公司号</lay-radio></lay-col>
                  <lay-col md="4">
                    <lay-radio v-model="selected" name="action" value="4" @change="queryConfig">数据准备</lay-radio>
                  </lay-col>
                  <lay-col md="4">
                    <lay-radio v-model="selected" name="action" value="6">SQL文件批量导入</lay-radio>
                  </lay-col>
                  <lay-col md="4"><lay-radio v-model="selected" name="action" value="5">See包比对</lay-radio></lay-col>
                  <lay-col md="4"><lay-radio v-model="selected" name="action" value="8">获取制品报告</lay-radio></lay-col>
                </lay-row>
                <lay-row>
                  <lay-col md="4"><lay-radio v-model="selected" name="action" value="3">查看日志</lay-radio></lay-col>
                  <lay-col md="4"><lay-radio v-model="selected" name="action" value="7">机器资源检查</lay-radio></lay-col>
                  <lay-col md="4"><lay-radio v-model="selected" name="action" value="9">远程执行命令</lay-radio></lay-col>
                </lay-row>
              </div>
            </lay-quote>
          </lay-col>
        </lay-row>
        <lay-row space="1">
          <lay-col md="22">
              <lay-form :model="params" ref="layFormRef4" required>
                  <lay-form-item label="公司名称" prop="name" v-if="selected == '2'">
                    <lay-select
                        v-model="params.company_no"
                        placeholder="请选择"
                        class="left-input"
                        showSearch
                    >
                      <lay-select-option
                          :value="unit.company_no"
                          :label="getCompanyName(unit)"
                          v-for="unit in company_names"
                          @click="changeCompany(unit)"
                      ></lay-select-option>
                    </lay-select>
                    <lay-button size="sm" type="normal" @click="confirmChange" class="right-input">切换公司号</lay-button>
                  </lay-form-item>
                  <lay-form-item label="环境名称" prop="database" v-if="selected !== '5' && selected !== '8'">
                    <lay-select
                        v-model="params.database"
                        placeholder="请选择"
                        class="left-input"
                        showSearch
                    >
                      <lay-select-option
                          :value="unit.name"
                          :label="unit.title"
                          v-for="unit in databases"
                          @click="changeEnv(unit)"
                      ></lay-select-option>
                    </lay-select>
                    <lay-button
                        size="sm"
                        type="normal"
                        class="right-input"
                        v-if="selected == '1'"
                        @click="checkEnvironmentMethod"
                    >环境检查</lay-button>
                  </lay-form-item>
                  <lay-form-item label="服务名称" prop="name" v-if="selected == '3'">
                    <lay-input v-model="params.server_name" placeholder="请输入，eg:com,ps,wl,pbs-server,..." class="left-input"></lay-input>
                    <lay-button size="sm" type="normal" @click="checkRemoteLog" class="right-input">查看日志</lay-button>
                  </lay-form-item>
                  <lay-form-item label="数据生成模板" prop="name" v-if="selected == '4'">
                    <lay-select v-model="params.module" placeholder="请选择" class="left-input"
                                @change="params.description = params.module">
                      <lay-select-option
                          :value="unit"
                          :label="unit"
                          v-for="unit in data_templates"
                      ></lay-select-option>
                    </lay-select>
                  </lay-form-item>
                  <lay-form-item label="数据场景描述" prop="name" v-if="selected == '4'">
                    <lay-textarea v-model="params.description"
                               placeholder="请输入数据生成要求，Eg:个人客户：国家代码为中国；基金交易：成交金额为500万，业务标识为认购"
                               class="left-input"
                               :rows="3"
                    ></lay-textarea>
                    <lay-button size="sm" type="normal" @click="mockAndInsertData" class="right-input">插入数据</lay-button>
                  </lay-form-item>
                  <!-- see包比对-->
                  <lay-form-item label="上一版本包" prop="name1" v-if="selected == '5'">
                     <lay-input v-model="params.rawPackage" placeholder="请复制制品库zip包下载连接.Eg:http://package.hundsun.com:80/artifactory/xxx/AML5.0-xx-01.zip" class="left-input"></lay-input>
                  </lay-form-item>
                  <lay-form-item label="当前版本包" prop="file" v-if="selected == '5'">
                    <lay-input v-model="params.targetPackage" placeholder="请复制制品库zip包下载连接.Eg:http://package.hundsun.com:80/artifactory/xxx/AML5.0-xx-02.zip" class="left-input"></lay-input>
                    <lay-button size="sm" type="normal" @click="compareZip" class="right-input">开始比对</lay-button>
                  </lay-form-item>
                  <!-- sql文件批量导入，上传zip包 -->
                  <lay-form-item label="数据库" prop="db" v-if="selected == '6'">
                    <lay-input v-model="params.user" placeholder="请输入数据库的用户和密码。格式：hsraw/hsraw" class="left-input"></lay-input>
                  </lay-form-item>
                  <lay-form-item label="SQL文件" prop="sqlZipFile" v-if="selected == '6'">
                     <lay-upload v-model="sqlZipFile" field="file" :auto="false" type="normal">
                        <template #preview>
                          {{ sqlZipFile[0]?.name }}
                        </template>
                     </lay-upload>
                    <lay-button size="sm" type="normal" @click="uploadAndExportSqlMethod" class="right-input">上传&导入</lay-button>
                  </lay-form-item>
                  <lay-form-item label="资源阈值" prop="name" v-if="selected == '7'">
                    <lay-input-number size="sm" type="normal" v-model="params.limit" :min="60" :max="100"></lay-input-number>
                    <lay-button size="sm" type="normal" @click="clearZipMethod" class="right-input">执行</lay-button>
                  </lay-form-item>
                  <lay-form-item label="制品库路径" prop="path" v-if="selected == '8'">
                    <lay-input size="sm"
                               type="normal"
                               v-model="params.path"
                               style="width: 80%;"
                               placeholder="请输入制品库的路径，例如:aml5.0-generic-test-local/os/AML5.0V202401/AML5.0V202401.10.7"
                    ></lay-input>
                    <lay-button size="sm" type="normal" @click="queryZipReport" class="right-input">查询</lay-button>
                  </lay-form-item>
                  <lay-form-item label="报告链接" prop="link" v-if="selected == '8'">
                      <a
                        v-if="params.link===''"
                          href="https://dev.hundsun.com/frameV2/cicd/artifacts"
                          target="_blank"
                          style="color: blue; text-decoration: none;"
                      >
                          暂无报告，制品库查看路径
                      </a>
                      <a style="color: blue; font-size: medium" target="_blank" :href="params.link" v-else>下载报告</a>
                  </lay-form-item>
                  <lay-form-item label="执行目录" prop="rootPath" v-if="selected == '9'">
                    <lay-input size="sm"
                               type="normal"
                               v-model="params.rootPath"
                               style="width: 60%;"
                               placeholder="请输入命令执行的目标目录，例如：Linux：/opt 或 Windows：D:\"
                    ></lay-input>
                    <lay-button size="sm" type="normal" @click="actCmds" style="margin-left: 15px">执行</lay-button>
                    <lay-button size="sm" @click="visibleName = !visibleName" style="margin-left: 15px">保存</lay-button>
                    <lay-dropdown>
                      <lay-button size="sm" @click="queryCmdRecord">常用命令</lay-button>
                      <template #content>
                          <lay-dropdown-menu>
                            <lay-dropdown-menu-item v-for="unit in cmd_list">
                              <a  @click="selectedHistoryCmd(unit)" style="width: 90%">{{unit.name}}</a>
                              <lay-icon type="layui-icon-close-fill" @click="deleteCmd(unit.id)" style="width: 10%; text-align: right; color: #f12626"></lay-icon>
                            </lay-dropdown-menu-item>
                          </lay-dropdown-menu>
                      </template>
                    </lay-dropdown>
                      <lay-layer v-model="visibleName" :shade="false" :area="['500px', '200px']">
                        <div style="padding: 20px;">
                          <lay-form :model="params" ref="layFormRef11" required>
                            <lay-form-item label="名称" prop="name">
                              <lay-input v-model="params.name"></lay-input>
                            </lay-form-item>
                          </lay-form>
                          <lay-form style="text-align: center;">
                            <lay-button size="sm" type="normal" @click="saveActCmd" style="margin-left: 15px">确认</lay-button>
                          </lay-form>
                        </div>
                      </lay-layer>
                  </lay-form-item>
                  <lay-form-item label="执行命令" prop="rootPath" v-if="selected == '9'">
                    <lay-textarea size="sm"
                               type="normal"
                               v-model="params.command"
                               style="width: 80%;"
                               placeholder="请输入待执行的命令，多条命令请换行"
                    ></lay-textarea>
                  </lay-form-item>
              </lay-form>
          </lay-col>
        </lay-row>
          <lay-row space="1">
            <lay-col md="24">
            <lay-fullscreen :target="elRef" v-slot="{ enter, exit, toggle, isFullscreen }" @fullscreenchange=fullscreen2>
              <div ref="elRef" class="wrapper-fullscreen">
                <lay-card>
                  <lay-button size="sm" @click="clearLog">清理日志</lay-button>
                  <lay-button size="sm" type="normal" @click="refreshLog">查看日志（手动刷新）</lay-button>
                  <lay-button size="sm" @click="resetRow">重置</lay-button>
                  <lay-button size="sm" type="normal" @click="toggle()"> 切换: {{isFullscreen ? "退出" : "进入全屏"}} </lay-button>
                  <lay-scroll :height="height" style="background-color: whitesmoke; margin-top: 5px;" >
                    <lay-container>
                      <p v-for="line in lines">
                        <span>{{ line }}</span>
                      </p>
                    </lay-container>
                  </lay-scroll>
                </lay-card>
              </div>
            </lay-fullscreen>
            </lay-col>
          </lay-row>
      </lay-col>
      <lay-col md="8">
        <lay-row space="5">
          <lay-col md="24">
            <lay-quote size="sm">
              <h3>环境信息:</h3>
            </lay-quote>
          </lay-col>
        </lay-row>
        <lay-row space="5">
          <lay-col md="24">
            <lay-scroll height="700px">
                <json-editor-vue
                  :currentMode="'view'"
                  :modeList="modeList"
                  :options="options"
                  class="editor"
                  v-model="jsonData"
                  :language="'zh-CN'"
                  style="height: 660px; width: 100%; position: relative"
                />
            </lay-scroll>
          </lay-col>
        </lay-row>
      </lay-col>
    </lay-row>
  </lay-card>
</template>

<script lang="ts">
export default {
    name: "AmlOperation"
}
</script>

<script setup lang="ts">

import {onMounted, onUnmounted, reactive, ref} from "vue";
import {
  changeLogApi,
  changeNoApi,
  checkAndClearZipApi,
  checkEnvironmentApi,
  compareZipApi,
  deleteCmdRecordApi,
  mockDataApi,
  queryCmdRecordApi,
  queryCompanyNos,
  queryConfigApi,
  queryDatabasesApi,
  queryEnvLogApi,
  queryZipReportApi,
  runCmdsApi,
  saveCmdApi,
  uploadAndImportSqlApi
} from "../../../api/fastApi/fastApi";
import {notify} from "../../../untils/tip";
import {layer} from "@layui/layui-vue";
import router from "../../../router/index";
import {CompanyNoVO} from "../../../untils/interfaceDefine";

onMounted(()=>{
  fetchCompanyNoData();
  queryDBS();
})

const visibleName = ref(false)
const visibleLog = ref(false)
const modeList= ref(["tree", "code", "view"]) // 可选模式
const height = ref("400px");
const databases = ref([])
const lines = ref([])
const row = ref(0)
const selected = ref('2');
const jsonData: any = ref(null);
const data_templates = ref([])
const sqlZipFile = ref([])
const params = reactive({
  database: '',
  company_no: '',
  rawPackage: '',
  targetPackage: '',
  company_name: '',
  server_name: '',
  company_title: '',
  description: '' ,
  env_title: '',
  module: '',
  path: '',
  link: '',
  rootPath: '',
  name: '',
  command: '',
  limit: 80,
  user: 'hsraw/hsraw',
})

const loading = ref(false)
const options = ref({
  navigationBar: false, // 是否显示导航栏
  view: { // 视图选项
    expanded: false // 不展开任何节点
  },
})

const company_names: any = ref([]);

const elRef = ref(null);
const fullscreen2 = function(isFullscreen){
  console.log(isFullscreen)
  if(isFullscreen){
    height.value = "1000px";
  }else {
    height.value = "440px";
  }
}
const queryDBS = async () => {
    let response = await queryDatabasesApi({});
    if(response.status === 200){
        databases.value = response.result;
        jsonData.value = response.data;
        company_names.value = response.list;
    }
    console.log("jsonData:", jsonData.value)
    const user_detail: any = localStorage.getItem('user_detail');
    console.log('user_detail:', user_detail)
    const user_info_cur = JSON.parse(user_detail);
    if(user_info_cur.tenant.id !== 2){
      jsonData.value = {"tip": "null"};
    }
}

const fetchCompanyNoData = async () => {
  await queryCompanyNos({}).then(res => {
    company_names.value = res.data;
  })
}

const getCompanyName = (unit: CompanyNoVO) => {
  let company_name = unit.company_name + '(' + unit.company_no + ')';
  if(unit.industry){
    company_name += '-' + unit.industry;
  }
  if(unit.db_type){
    company_name += '-' + unit.db_type;
  }
  return company_name;
}

const queryConfig = async () => {
    let response = await queryConfigApi({project: '金融反洗钱项目', method: 'json'});
    if(response.status === 200){
      data_templates.value = response.content.DataMockModule.list;
      lines.value = response.content.DataMockModule.content;
    }
}

const uploadAndExportSqlMethod = async () => {
  if(!sqlZipFile.value[0] && sqlZipFile.value[0].name.endsWith('.zip')){
    layer.msg('请将SQL文件（.txt,.sql）压缩成.zip包进行上传')
    return
  }else {
    layer.msg('开始上传SQL文件，解压之后异步导入数据库，请稍等... 可以刷新日志查看导入过程')
  }
  const formData = new FormData();
  formData.append('env', params.database);
  formData.append('user', params.user);
  formData.append('sqlZip', sqlZipFile.value[0]);
  console.log('req_params:', formData)
  let response = await uploadAndImportSqlApi(formData);
  notify(response.status, response.message);
}

const changeCompany = (node: any) => {
    params.company_no = node.company_no;
    params.company_name = node.company_name;
    params.company_title = node.company_no + '|' + node.company_name;
    if(node.env_name){
      params.database = node.env_name;
    }
    console.log("current params :", params)
}

const changeEnv = (node: any) => {
    params.env_title = node.title;
}

const compareZip = async () => {
  const token : any = localStorage.getItem('token');
  const token_info = JSON.parse(token);
  const formData = new FormData();
  formData.append('name', token_info.userInfo.username);
  formData.append('raw', params.rawPackage);
  formData.append('target', params.targetPackage);
  let response = await compareZipApi(formData)
  notify(response.status, response.message)
  lines.value.push(response.data)
}

const clearZipMethod = async () => {
  const paramsJson = reactive({envs: [params.database], limit: params.limit});
  let response = await checkAndClearZipApi(paramsJson)
  notify(response.status, response.message)
}

const queryZipReport = async () => {
  const paramsJson = reactive({path: params.path});
  let response = await queryZipReportApi(paramsJson);
  params.link = response.data;
  notify(response.status, response.message)
}

const actCmds = async () => {
  const paramsJson = reactive({env: params.database, path: params.rootPath, command: params.command});
  lines.value.push("执行命令中，请稍等...")
  lines.value.push(paramsJson)
  if(!paramsJson.command || !paramsJson.path){
    layer.msg('请填写待命令执行时的目录或目录')
    return
  }else {
    let response = await runCmdsApi(paramsJson);
    params.link = response.data;
    notify(response.status, response.message)
  }
}

const saveActCmd = async () => {
  const paramsJson = reactive({
    id: null,
    env: params.database,
    path: params.rootPath,
    command: params.command,
    name: params.name,
    description: 'Web保存'
  });
  let response = await saveCmdApi(paramsJson);
  notify(response.status, response.message)
}


const cmd_list = ref([])
const queryCmdRecord = async () => {
  let response = await queryCmdRecordApi({});
  cmd_list.value = response.data;
}

const selectedHistoryCmd = (item: any) => {
  console.log(item)
  params.rootPath = item.path;
  params.command = item.command;
  params.database = item.env;
  layer.msg("添加："+item.name)
}

const deleteCmd = async (id: number) => {
  let response = await deleteCmdRecordApi({id: id});
  layer.msg(response.message)
};

const submitFile = async () => {
  const token : any = localStorage.getItem('token');
  const token_info = JSON.parse(token);
  const formData = new FormData();
  const relogin = token_info.userInfo.username ? false : null;
  formData.append('name', token_info.userInfo.username ? token_info.userInfo.username : null);
  formData.append('env', params.database);
  formData.append('company_no', params.company_no);
  formData.append('company_name', params.company_name);
  console.log('submit form data:', formData)
  if(relogin === null){
    notify('Failed', '请退出重新登录！')
    await router.push("/user/login")
    return
  }else {
    let response = await changeNoApi(formData);
    notify(response.status, response.message)
  }
}

const confirmChange = async () => {
   layer.confirm("请确认公司号【" + params.company_title + "】和环境【" + params.env_title + "】是否符合期望？",
      {
          btn: [
              {
                  text: '继续', callback: (id: number) => {
                      submitFile();
                      layer.close(id);
                  }
              },
              {
                  text: '取消', callback: (id: number) => {
                      layer.close(id);
                  }
              }
          ]
      }
   )
}

const mockAndInsertData = async () => {
  const layId = ref()
  layId.value = layer.load(0, { time: 10000 })
  const formData = new FormData();
  formData.append('env', params.database);
  formData.append('description', params.description);
  let response = await mockDataApi(formData);
  notify(response.status, response.message)
  lines.value = response.content;
  layer.close(layId.value)
}

const checkRemoteLog = async () => {
  const formData = new FormData();
  formData.append('env', params.database);
  formData.append('server', params.server_name);
  let response = await changeLogApi(formData);
  notify(response.status, response.message)
  lines.value = response.content;
}

const checkEnvironmentMethod = async () => {
    let response = await checkEnvironmentApi({env: params.database});
    notify(response.status, response.message)
}

const clearLog = () => {
  lines.value = []
}

const resetRow = () => {
  row.value = 0;
  if(timerInsert.value){
    clearInterval(timerInsert.value);
  }
  timerInsert.value = ''
}

const queryEnvLogMethod = async () => {
    let response = await queryEnvLogApi({row: row.value});
    if(response.status === 200){
      response.result.forEach((unit: string)=>{lines.value.push(unit)})
      row.value = row.value + response.result.length;
    }
}


const timerInsert = ref();
const times = ref()

const refreshLog = () => {
  // timerInsert.value = setInterval(queryEnvLogMethod, 3000)
  queryEnvLogMethod();
}

// 销毁前清理定时任务
onUnmounted(() => {
  resetRow();
})
</script>

<style scoped>
.left-input {
  width: 80%;
  float: left;
}
.right-input {
  float: right;
  margin-left: 20px;
}

</style>